package com.autumn.platform.dao.dialect.impl;

import java.util.Iterator;
import java.util.regex.Pattern;

import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Order;

import com.autumn.platform.dao.dialect.IDialect;

public abstract class AbstractDialect implements IDialect {

    private static final Pattern SORT_PATTERN = Pattern.compile("\\s+order\\s+by\\s+(?![^\\)]+\\))[^\\)]+$", Pattern.CASE_INSENSITIVE);

    @Override
    public boolean match(String databaseId) {
        return null != databaseId && databaseId.equalsIgnoreCase(getDatabaseId());
    }

    @Override
    public String getTotalSql(String sql) {
        StringBuilder rs = new StringBuilder();
        rs.append("select count(1) total_ from (").append(sql).append(") total_ ");
        return rs.toString();
    }

    @Override
    public String getPageableSql(String sql, Pageable pageable) {
        sql = this.removeOldSortSqlIfNeed(sql, pageable.getSort());
        if (pageable.isPaged()) {
            sql = this.getPageSql(sql, pageable);
        } else {
            sql += this.getSortSql(pageable.getSort());
        }
        return sql;
    }

    private String removeOldSortSqlIfNeed(String sql, Sort sort) {
        if (null != sort && sort.isSorted()) {
            sql = SORT_PATTERN.matcher(sql).replaceFirst("");
        }
        return sql;
    }

    protected abstract String getPageSql(String sql, Pageable pageable);

    /**
     * 获取排序语句
     * 
     * @param sort
     * @return
     */
    protected String getSortSql(Sort sort) {
        if (null != sort && sort.isSorted()) {
            StringBuilder sb = new StringBuilder();
            Iterator<Order> iterator = sort.iterator();
            if (null != iterator) {
                for (; iterator.hasNext();) {
                    Order order = iterator.next();
                    sb.append(",").append(order.getProperty());
                    if (order.isDescending()) {
                        sb.append(" DESC");
                    }
                }
                return " ORDER BY " + sb.deleteCharAt(0).toString();
            }
        }
        return "";
    }
}
